<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input
        style="width: 200px;"
        class="filter-item"
        placeholder="角色名"
        v-model="queryForm.name"
      >
      </el-input>
      <el-select
        clearable
        style="width: 200px"
        class="filter-item"
        v-model="queryForm.type"
        placeholder="角色类别"
      >
        <el-option
          v-for="(val, key) in typeOptions"
          :key="key"
          :label="val"
          :value="key"
        >
        </el-option>
      </el-select>
      <el-button
        class="filter-item"
        @click="doQuery"
        type="primary"
        icon="el-icon-search"
        >查询</el-button
      >
      <el-button
        v-permission="'role:add'"
        class="filter-item"
        @click="openCreateDialog(null)"
        type="success"
        icon="el-icon-edit"
        >新增</el-button
      >
    </div>
    <el-table v-loading="loading" :data="records" style="width: 100%">
      <el-table-column
        prop="code"
        label="角色代码"
        min-width="20%"
        align="center"
      >
      </el-table-column>
      <el-table-column
        prop="name"
        label="角色名"
        min-width="20%"
        align="center"
      >
      </el-table-column>
      <el-table-column
        prop="type"
        label="角色类型"
        min-width="20%"
        align="center"
      >
        <template slot-scope="scope">
          {{ Dicts.ROLE_TYPE[scope.row.type] }}
        </template>
      </el-table-column>
      <el-table-column
        prop="attr"
        label="角色级别"
        min-width="20%"
        align="center"
      >
      </el-table-column>
      <el-table-column
        prop="description"
        label="角色描述"
        min-width="20%"
        align="center"
      >
      </el-table-column>
      <el-table-column
        width="300"
        align="center"
        label="操作"
        class-name="small-padding"
        fixed="right"
      >
        <template slot-scope="scope">
          <el-button
            v-permission="'role:update'"
            @click="editRoleForm(scope.row.rowId)"
            type="success"
            size="mini"
            icon="el-icon-edit"
            circle
            title="修改"
          ></el-button>
          <el-button
            v-permission="'role:showAssignModule'"
            @click="showAssignModule(scope.row.rowId)"
            type="warning"
            size="mini"
            icon="el-icon-message"
            circle
            title="分配模块"
          ></el-button>
          <el-button
            v-permission="'role:showAssignOperation'"
            @click="showAssignOperation(scope.row.rowId)"
            type="info"
            size="mini"
            icon="el-icon-plus"
            circle
            title="分配权限"
          ></el-button>
          <el-button
            v-permission="'role:delete'"
            @click="handleDelete(scope.row.rowId)"
            size="mini"
            type="danger"
            icon="el-icon-delete"
            circle
            title="删除"
          ></el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination-container">
      <el-pagination
        background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="queryForm.current"
        :page-sizes="[10, 20, 30, 50]"
        :page-size="queryForm.size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="queryForm.total"
      >
      </el-pagination>
    </div>
    <!-- 修改|新增角色信息弹框 -->
    <el-dialog
      :title="`${editForm.rowId ? '编辑' : '新增'}角色信息`"
      :visible.sync="dialogFormVisible"
      width="30%"
    >
      <el-form
        :model="editForm"
        label-width="100px"
        :rules="editFormRules"
        ref="editForm"
      >
        <el-form-item label="角色代码:" prop="code">
          <el-input
            :disabled="disabled"
            v-model="editForm.code"
            auto-complete="off"
            ref="code"
          ></el-input>
        </el-form-item>
        <el-form-item label="角色名:" prop="name">
          <el-input v-model="editForm.name" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色类型:" prop="type">
          <el-select
            v-model="editForm.type"
            placeholder="角色类型"
            style="width: 100%;"
          >
            <el-option
              v-for="(val, key) in Dicts.ROLE_TYPE"
              :key="key"
              :label="val"
              :value="key"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="角色级别:" prop="attr">
          <el-input v-model="editForm.attr" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色描述:" prop="description">
          <el-input
            type="textarea"
            v-model="editForm.description"
            auto-complete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveRole(editForm.rowId)"
          >确 定</el-button
        >
      </div>
    </el-dialog>
    <!-- 分配模块 -->
    <el-dialog title="模块分配" :visible.sync="dialogModuleVisible" width="30%">
      <el-form :model="modules" label-width="80px" ref="modules">
        <el-tree
          :data="modules"
          show-checkbox
          node-key="id"
          highlight-current
          :props="defaultProps"
          ref="tree"
        >
        </el-tree>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogModuleVisible = false">取 消</el-button>
        <el-button
          type="primary"
          @click="grantModulePower(roleId)"
          :v-model="roleId"
          >确 定</el-button
        >
      </div>
    </el-dialog>
    <!-- 分配权限 -->
    <el-dialog
      title="分配权限"
      :visible.sync="dialogOperationVisible"
      width="30%"
    >
      <el-form :model="operations" label-width="80px" ref="operations">
        <el-tree
          :data="operations.treeNodes"
          show-checkbox
          node-key="id"
          highlight-current
          :default-checked-keys="operations.defaultCheckKey"
          :props="defaultProps"
          ref="operationTree"
        >
        </el-tree>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogOperationVisible = false">取 消</el-button>
        <el-button
          type="primary"
          @click="grantOperationPower(roleId)"
          :v-model="roleId"
          >确 定</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  queryRole,
  deleteRole,
  addOrEditRole,
  detailRole,
  queryAllModule,
  queryRoleOperation,
  grantModulePower,
  grantOperationPower
} from '@/api/system'

export default {
  data() {
    var checkName = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('名称不能为空'))
      }
      if (
        /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im.test(value) ||
        /[·！#￥（——）：；“”‘、，|《。》？、【】[\]]/im.test(value)
      ) {
        callback(new Error('请输入合法名称'))
      } else {
        callback()
      }
    }
    return {
      dialogFormVisible: false, // 角色详情弹框可视标志
      dialogModuleVisible: false, // 模块分配弹框可视标志
      dialogOperationVisible: false, // 操作权限分配弹框可视标志
      loading: false,
      queryForm: {
        current: 1,
        pages: 0,
        total: 0,
        size: 10,
        name: undefined,
        type: undefined
      },
      editFormRules: {
        name: [{ validator: checkName, trigger: 'blur' }],
        code: [{ validator: checkName, trigger: 'change' }],
        type: [
          { required: true, message: '角色类型不能为空', trigger: 'change' }
        ]
      },
      editForm: {
        rowId: 0,
        code: '',
        name: '',
        attr: '',
        description: ''
      },
      // 模块树数据绑定
      modules: [], // 模块树节点集合
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      rolePower: {
        roleId: undefined,
        keys: [] // 角色选中的节点集合
      },
      roleId: undefined, // 权限分配时保存的角色ID
      disabled: true,
      typeOptions: Dicts.ROLE_TYPE,
      records: [],
      operations: {
        treeNodes: [], // 操作树节点集合
        defaultCheckKey: [] // 默认选中的节点集合
      }
    }
  },
  created() {
    this.doQuery()
  },
  methods: {
    handleCurrentChange(current) {
      this.queryForm.current = current
      this.doQuery()
    },
    handleSizeChange(size) {
      this.queryForm.size = size
      this.doQuery()
    },
    doQuery() {
      this.loading = true
      queryRole(this.queryForm).then(({ data: { data } }) => {
        this.queryForm.current = data.current
        this.queryForm.pages = data.pages
        this.queryForm.total = data.total
        this.queryForm.size = data.size
        this.records = data.records
        this.loading = false
      })
    },
    handleDelete(rowId) {
      this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteRole(rowId).then(({ data: { data, msg } }) => {
          this.doQuery()
          this.$message({
            showClose: true,
            message: msg,
            type: 'success'
          })
        })
      })
    },
    editRoleForm(rowId) {
      detailRole(rowId).then(({ data: { data } }) => {
        this.openCreateDialog(rowId)
        this.editForm = {
          rowId: data.rowId,
          code: data.code,
          name: data.name,
          type: data.type,
          attr: data.attr,
          description: data.description
        }
      })
    },
    saveRole(rowId) {
      this.$refs.editForm.validate(valid => {
        if (valid) {
          addOrEditRole(this.editForm).then(({ data: { data, msg, code } }) => {
            if (code === 0) {
              this.doQuery()
              this.dialogFormVisible = false
            }
            this.$message({
              showClose: true,
              message: msg,
              type: code === 0 ? 'success' : 'error'
            })
          })
        }
      })
    },
    /**
     * 查看角色当前模块权限
     */
    showAssignModule(rowId) {
      this.roleId = rowId
      queryAllModule(rowId).then(({ data: { data } }) => {
        this.openModuleDialog()
        this.modules = data.module
        this.$nextTick(() => {
          this.$refs.tree.setCheckedKeys(data.roleModules)
        })
      })
    },
    /**
     * 给角色分配模块权限
     */
    grantModulePower() {
      this.rolePower.roleId = this.roleId
      this.rolePower.keys = this.$refs.tree.getCheckedKeys()
      this.rolePower.keys = this.rolePower.keys.concat(
        this.$refs.tree.getHalfCheckedKeys()
      )
      if (this.rolePower.keys.length === 0) {
        this.$message({
          showClose: true,
          message: '请勾选模块',
          type: 'warning'
        })
        return false
      }
      grantModulePower(this.rolePower).then(({ data: { data, msg, code } }) => {
        if (code === 0) {
          this.doQuery()
          this.dialogModuleVisible = false
        }
        this.$message({
          showClose: true,
          message: msg,
          type: code === 0 ? 'success' : 'error'
        })
      })
    },
    /**
     * 展示角色操作权限
     */
    showAssignOperation(roleId) {
      this.roleId = roleId
      queryRoleOperation(roleId).then(({ data: { data } }) => {
        this.openOperationDialog()
        this.operations.treeNodes = data.treeNodes
        this.operations.defaultCheckKey = data.codeList
      })
    },
    /**
     * 给角色分配操作权限
     */
    grantOperationPower(roleId) {
      this.rolePower.roleId = this.roleId
      this.rolePower.keys = this.$refs.operationTree.getCheckedKeys()
      if (this.rolePower.keys.length === 0) {
        this.$message({
          showClose: true,
          message: '请勾选权限',
          type: 'warning'
        })
        return false
      }
      grantOperationPower(this.rolePower).then(
        ({ data: { data, msg, code } }) => {
          if (code === 0) {
            this.doQuery()
            this.dialogOperationVisible = false
          }
          this.$message({
            showClose: true,
            message: msg,
            type: code === 0 ? 'success' : 'error'
          })
        }
      )
    },
    /**
     * 打开分配操作权限弹框
     */
    openOperationDialog() {
      this.operations = {
        treeNodes: [],
        defaultCheckKey: []
      }
      this.dialogOperationVisible = true
      this.$refs.operations && this.$refs.operations.resetFields()
    },
    /**
     * 打开模块分配弹框
     */
    openModuleDialog() {
      this.modules = []
      this.dialogModuleVisible = true
      this.$refs.modules && this.$refs.modules.resetFields()
    },
    openCreateDialog(rowId) {
      this.editForm = {}
      this.dialogFormVisible = true
      this.$refs.editForm && this.$refs.editForm.resetFields()
      this.disabled = rowId != null
    }
  },
  components: {}
}
</script>

<style scoped></style>
